<?php

declare(strict_types=1);

namespace Service\GoodsService;

use App\Model\BbcModel\CommentSure;
use App\Model\BbcModel\CommentTags;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\GoodsComment;
use App\Model\BbcModel\GoodsCommentAttach;
use App\Model\BbcModel\GoodsCommentTags;
use App\Model\BbcModel\MemberInfo;
use App\Model\BbcModel\Order;
use App\Model\BbcModel\OrderGoods;
use Service\BaseService;
use Service\Code\Normal;

/*
 * 商品评论服务中心
 * @author Luoshumai
 */

class GoodsCommentService extends BaseService
{
    /**
     * 获取评论列表
     * @param int $goods_id
     * @param int $page
     * @param int $limit
     * @param int $tag_id
     * @param int $cid
     * @param int $mid
     * @return array
     */
    public function getComments(int $goods_id, int $page, int $limit, int $tag_id, int $cid, int $mid)
    {
        if (empty($goods_id)) {
            return Normal::returnCode(Normal::FAIL, 'except param goods_id');
        }

        $tags = CommentTags::instance()
            ->from(CommentTags::instance()->getTable() . ' ct')
            ->join(GoodsCommentTags::instance()->getTable() . ' as gct', 'gct.id', '=', 'ct.tag_id')
            ->where([
                'ct.goods_id' => $goods_id,
                'ct.check_status' => 1,
                'gct.cid' => $cid,
                'gct.show' => 1
            ])->select([
                'ct.tag_id', 'gct.name tag_name', 'ct.comment_id'
            ])->get()->toArray();

        $tagCommentIdMap = array_column($tags, 'comment_id', 'tag_name');


        $query = GoodsComment::instance()
            ->from(GoodsComment::instance()->getTable() . 'gc')
            ->where([
                'gc.goods_id' => $goods_id,
                'gc.check_status' => 1,
                'gc.df' => 0,
            ]);

        if (!empty($tag_id)) {
            $query->join(CommentTags::instance()->getTable() . ' ct', 'ct.comment_id', '=', 'gc.id')
                ->where([
                    'ct.goods_id' => $goods_id,
                    'ct.df' => 0,
                    'ct.check_status' => 1,
                    'ct.tag_id' => $tag_id,
                ]);
        }

        $pageInfo = $query->paginate($limit, ['gc.id as comment_id', 'gc.nickname', 'gc.avatar', 'gc.content', 'gc.star', 'gc.type', 'gc.cd', 'gc.sure'], 'page', $page)
            ->toArray();


        $list = $pageInfo['data'];

        $attachMap = $commentSures = [];
        //查询评论附件
        if (!empty($list)) {
            $commentIds = array_column($list, 'comment_id');
            $attachs = GoodsCommentAttach::instance()->whereIn('comment_id', $commentIds)->select(['comment_id', 'url'])->get()->toArray();
            foreach ($attachs as $attach) {
                $attachMap[$attach['comment_id']][] = $attach['url'];
            }
            if (!empty($mid)) {
                $commentSures = CommentSure::instance()->where('mid', $mid)->whereIn('comment_id', $commentIds)->pluck('comment_id');
            }
        }

        foreach ($list as &$item) {
            $item['cd'] = date('Y-m-d H:i:s');
            $item['attach'] = $attachMap[$item['comment_id']] ?? [];
            $item['tags'] = $tagCommentIdMap[$item['comment_id']] ?? [];
            $item['doSure'] = in_array($item['comment_id'], $commentSures) ? 1 : 0;
        }

        return Normal::returnCode(Normal::SUC, '获取成功', [
            'list' => $list,
            'total' => $pageInfo['total'],
            'all_tags' => $tags
        ]);
    }

    /**
     * 获取标签列表
     * @param int $cid
     * @return array
     */
    public function getTags(int $cid)
    {
        if (empty($cid)) {
            return Normal::returnCode(Normal::FAIL, 'except param cid');
        }
        $list = GoodsCommentTags::instance()->where([
            'cid' => $cid,
            'df' => 0,
            'show' => 1,
        ])->select(['id', 'name'])->get()->toArray();

        return Normal::returnCode(Normal::SUC, '获取成功', $list);
    }


    /**
     * 添加评论
     * @param int $cid
     * @param int $comment_id
     * @param int $mid
     * @return array
     */
    public function addComment(array $comment_list, int $cid, string $sn, int $anonymity, int $mid)
    {
        if (empty($comment_list)) {
            return Normal::returnCode(Normal::FAIL, 'except param comment_list');
        }
        if (empty($mid)) {
            return Normal::returnCode(Normal::FAIL, 'except param mid');
        }
        if (!is_array($comment_list)) {
            return Normal::returnCode(Normal::FAIL, 'comment_list is not array');
        }
        if (empty($sn)) {
            return Normal::returnCode(Normal::FAIL, 'except param sn');
        }

        $memberInfo = MemberInfo::instance()->info(['mid' => $mid]);

        $order = Order::instance()->info(['sn' => $sn, 'mid' => $mid]);
        if (empty($order)) {
            return Normal::returnCode(Normal::FAIL, 'except param order');
        }
        if ($order['status'] != 50 || $order['is_comment'] != 0) {
            return Normal::returnCode(Normal::FAIL, '订单状态不是待评价');
        }


        GoodsComment::instance()->startTrans();
        try {
            $insertComments = $insertCommentsImgs = $insertCommentsTags = $editOrderGoodsIds = [];

            foreach ($comment_list as $comment) {

                if (empty($comment['goods_id'])) {
                    throw new \Exception('except param goods_id');
                }
                if (empty($comment['content'])) {
                    throw new \Exception('except param content');
                }
                if (mb_strlen($comment['content']) > 240) {
                    throw new \Exception('评论不能超过240个字');
                }
                $orderGoodsObj = OrderGoods::instance()
                    ->from(OrderGoods::instance()->getTable() . ' og')
                    ->join(Goods::instance()->getTable() . ' g', 'g.')
                    ->select(['og.id', 'og.is_comment', 'og.goods_name', 'g.img', 'g.skucode', 'g.barcode'])
                    ->where(['og.order_id' => $order['id'], 'og.goods_id' => $comment['goods_id']])->first();

                if (empty($orderGoodsObj)) {
                    throw new \Exception('订单商品不存在');
                }
                $orderGoods = $orderGoodsObj->toArray();

                if ($orderGoods['is_comment'] == 1) {
                    throw new \Exception('此商品已评价');
                }
                if (!empty($comment['img']) && !is_array($comment['img'])) {
                    throw new \Exception('图片请传数组');
                }
                if (!empty($comment['tags']) && !is_array($comment['tags'])) {
                    throw new \Exception('标签请传数组');
                }

                $insertComment = [
                    'cid' => $order['cid'],
                    'sn' => $order['sn'],
                    'mid' => $order['mid'],
                    'sid' => getSID(),
                    'pay_sn' => $order['pay_sn'],
                    'mn_sid' => $order['mn_sid'],
                    'order_id' => $order['order_id'],
                    'buyer_name' => $order['buyer_name'],
                    'buyer_mobile' => $order['buyer_mobile'],
                    'goods_id' => $comment['goods_id'],
                    'goods_name' => $orderGoods['goods_name'],
                    'goods_img' => $orderGoods['goods_img'],
                    'skucode' => $orderGoods['skucode'],
                    'barcode' => $orderGoods['barcode'],
                    'anonymity' => $comment['anonymity'],
                    'content' => $comment['content'],
                    'nickname' => $comment['anonymity'] == 1 ? $this->_anonymousName($memberInfo['nickname']) : $memberInfo['nickname'],
                    'avatar' => $comment['anonymity'] == 1 ? $memberInfo['avatar'] : '',
                    'star' => $comment['star'],
                    'user_type' => 1,
                    'type' => !empty($comment['img']) ? 1 : 0,
                    'cd' => time(),
                ];
                $goodsCommentId = GoodsComment::instance()->insertGetId($insertComment);
                $editOrderGoodsIds[] = $editOrderGoodsIds;

                if (!empty($comment['img'])) {
                    foreach ($comment['img'] as $url)
                        $insertCommentsImgs[] = [
                            'comment_id' => $goodsCommentId,
                            'type' => 1,
                            'sid' => $order['sid'],
                            'mid' => $mid,
                            'url' => $url
                        ];
                }

                if (!empty($comment['tags'])) {
                    foreach ($comment['tags'] as $tag_id)
                        $insertCommentsTags[] = [
                            'cid' => $cid,
                            'sid' => getSID(),
                            'comment_id' => $goodsCommentId,
                            'goods_id' => $comment['goods_id'],
                            'tag_id' => $tag_id
                        ];
                }
            }

            //批量修改
            OrderGoods::instance()->whereIn('id', $editOrderGoodsIds)->update(['is_comment' => 1]);
            //批量添加
            GoodsCommentAttach::instance()->insert($insertCommentsImgs);
            CommentTags::instance()->insert($insertCommentsTags);
        } catch (\Exception $e) {
            GoodsComment::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, $e->getMessage());
        }

        GoodsComment::instance()->commit();
        return Normal::returnCode(Normal::SUC, '评论成功');
    }

    /**
     * 匿名名称
     * @return string
     */
    private function _anonymousName(string $nickname)
    {
        if (mb_strlen($nickname) <= 2) {
            $nameless = '**';
        } else {
            $first = mb_substr($nickname, 0, 1);
            $end = mb_substr($nickname, -1, 1);
            $nameless = $first . '**' . $end;
        }
        return $nameless;
    }

    /**
     * 评论点赞
     * @param int $cid
     * @param int $comment_id
     * @param int $mid
     * @return array
     */
    public function doLikeComment(int $cid, int $comment_id, int $mid)
    {
        if (empty($mid)) {
            return Normal::returnCode(Normal::FAIL, '请先登录');
        }
        if (empty($comment_id)) {
            return Normal::returnCode(Normal::FAIL, 'except param comment_id');
        }
        $isExist = CommentSure::instance()->info(['mid' => $mid, 'comment_id' => $comment_id]);
        if ($isExist) {
            return Normal::returnCode(Normal::SUC, '点赞成功');
        }

        Goodscomment::instance()->where(['id' => $comment_id])->increment('sure');
        return Normal::returnCode(Normal::SUC, '点赞成功');
    }


    /**
     * 评论点赞
     * @param int $cid
     * @param int $comment_id
     * @param int $mid
     * @return array
     */
    public function cancelLikeComment(int $cid, int $comment_id, int $mid)
    {
        if (empty($mid)) {
            return Normal::returnCode(Normal::FAIL, '请先登录');
        }
        if (empty($comment_id)) {
            return Normal::returnCode(Normal::FAIL, 'except param comment_id');
        }
        $isExist = CommentSure::instance()->info(['mid' => $mid, 'comment_id' => $comment_id]);
        if (!$isExist) {
            return Normal::returnCode(Normal::SUC, '取消成功');
        }

        Goodscomment::instance()->where(['id' => $comment_id])->decrement('sure');
        return Normal::returnCode(Normal::SUC, '取消成功');
    }
}